package com.hap.spring;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ClassPathXmlApplocationContext implements BeanFactory {
    private Map<String, Object> map = new HashMap<>();
    private List<Bean> beanAll = new ArrayList<>();

    public ClassPathXmlApplocationContext() {
        try {
            readXml();
            instanceBean();
            setProperty();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Object getBean(String id) {
        return map.get(id);
    }

    public void readXml() throws DocumentException {
        System.out.println("读取XML文件...");
        //创建读取对象
        SAXReader sax = new SAXReader();
        //加载配置文件，返回文档对象
        Document doc = sax.read(this.getClass().getResource("bean.xml"));
        //获取根节点
        Element root = doc.getRootElement();
        //根据根节点获取子节点
        List<Element> beans = root.elements();
        for (Element bean : beans) {
            String id = bean.attributeValue("id");
            String type = bean.attributeValue("class");
            Bean b = new Bean(id, type);
            System.out.println(id + "----" + type);
            List<Element> properties = bean.elements();
            if (properties != null && properties.size() > 0) {
                Map<String, String> mp = new HashMap<>();
                for (Element property : properties) {
                    String name = property.attributeValue("name");
                    String ref = property.attributeValue("ref");
                    mp.put(name, ref);
                }
                b.setProperties(mp);
            }
            beanAll.add(b);
        }
        System.out.println(beanAll);
        System.out.println("读取xml完毕...");
    }

    public void instanceBean() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        System.out.println("初始化bean对象开始...");
        for (Bean bean : beanAll) {
            Class<?> cls = Class.forName(bean.getType());
            Object obj = cls.newInstance();
            map.put(bean.getId(), obj);
        }
        System.out.println(map);
        System.out.println("初始化bean对象结束...");

    }

    public void setProperty() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        System.out.println("设置属性开始...");
        for (Bean bean : beanAll) {
            Object obj = map.get(bean.getId());
            Map<String, String> properties = bean.getProperties();
            if (properties != null && properties.size() > 0) {
                for (String name : properties.keySet()) {
                    String ref = properties.get(name);
                    Object property = map.get(ref);
                    String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
                    Method method = obj.getClass().getMethod(methodName, property.getClass().getInterfaces()[0]);
                    method.invoke(obj, property);
                }
            }
        }
        System.out.println("设置属性结束...");
    }

    public static void main(String[] args) {
        new ClassPathXmlApplocationContext();

    }
}
